﻿using Unity.Burst;
using Unity.Collections;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.ParticleSystemJobs;
using Yoozoo.Gameplay.RTS;

namespace Yoozoo.Mars.Got.SpriteAnim
{
   // [BurstCompile]
    //public struct UpdateParticleJob : IJobParticleSystem
    public struct UpdateParticleJob : IJobParticleSystemParallelForBatch
    {
        public float deltaTime;
        
        // 该动作是不是十六方向，索引为动作代号
        [ReadOnly]
        public NativeArray<bool> isDirect16;
        // 动画分成 动作 和 方向 两个部分
        // 动作的编号见：SPRITE_ACTION_ENUM，目前只用到0~5这6个动作
        // 方向的编号见：DIRCTION_INDEX_ENUM, 但实际只有5方向，左右会翻转处理
        // 由于 ParticleSystemJobData 使用 aliveTimePercent, 所以这里也用这种方式记录动画的起始和结束时间
        // 动画信息的索引 = 动作编号 * 方向数 + 方向编号

        /// <summary>
        /// 动画开始时的aliveTimePercent
        /// </summary>
        [ReadOnly]
        public NativeArray<float> startAliveTimePercents;

        /// <summary>
        /// 动画结束时的aliveTimePercent
        /// </summary>
        [ReadOnly]
        public NativeArray<float> endAliveTimePercents;

        [ReadOnly] public NativeArray<float> changeColorOffsetX;
        [ReadOnly] public NativeArray<float> changeColorOffsetY;
        [ReadOnly] public NativeArray<float> changeColorOffsetX2;
        [ReadOnly] public NativeArray<float> changeColorOffsetY2;
        [ReadOnly] public NativeArray<float> startOffsetX;
        [ReadOnly] public NativeArray<float> startOffsetY;
        [ReadOnly] public NativeArray<float> rectWidth;
        [ReadOnly] public NativeArray<float> rectHeight;
        
        [ReadOnly] public float allLifeTime;

        [ReadOnly] public float customLifetime;
        
        public NativeArray<float> realAliveTimePercents;
        public AnimSpriteCreatorData data;

        //public void Execute(ParticleSystemJobData particles)
        public void Execute(ParticleSystemJobData particles, int startIndex, int count)
        {
            var startColors = particles.startColors;
            var sizeX = particles.sizes.x;
            var sizeY = particles.sizes.y;
            var sizeZ = particles.sizes.z;
            var positionX = particles.positions.x;
            var positionY = particles.positions.y;
            var positionZ = particles.positions.z;
            var aliveTimePercents = particles.aliveTimePercent;

            var customData = particles.customData1;
            var customData2 = particles.customData2;
            
            int particleCount = startIndex + count;
            //if(particleCount > 8000)
                //Debug.LogErrorFormat("UpdateParticleJob, start {0} count {1}", startIndex, count);
            for (int i = startIndex; i < particleCount; i++)
            //int particleCount = particles.count;
            //for (int i = 0; i < particleCount; i++)
            {
                
                // 处理移除粒子，将生存时间设为100%即可
                if (data.removes[i]) {
                    aliveTimePercents[i] = 100;
                    data.removes[i] = false;
                    continue;
                }
                
                
                // 设置透明度
                byte alpha = data.alphas[i];
                var color = startColors[i];
                color.a = alpha;
                startColors[i] = color;
                // 根据rotation计算动画方向，判断是否需要翻转，设置size
                float3 rotation = data.rotations[i];
                float spriteSize = data.spriteSizes[i];
                int action = data.actions[i];
                bool isd16 = isDirect16[action];
                int direction = ParticleJobHelper.GetDirection(rotation,isd16 );
                bool flip = ParticleJobHelper.GetFlip(direction, isd16);

                if (flip)
                {
                    sizeX[i] = -spriteSize;
                    sizeY[i] = spriteSize;
                    sizeZ[i] = 1;
                }
                else
                {
                    sizeX[i] = spriteSize;
                    sizeY[i] = spriteSize;
                    sizeZ[i] = 1;
                }
                // 设置位置
                float3 position = data.positions[i];
                float3 offset = data.offsets[i];
                positionX[i] = position.x + offset.x;
                positionY[i] = position.y + offset.y;
                positionZ[i] = position.z + offset.z;
                
                // 根据动作编号和方向确定要播放的动画
                int animationIndex = ParticleJobHelper.GetAnimationIndex(direction, isd16);
                int index = action * 9 + animationIndex;
                // 读取动画的开始时间和结束时间
                float start = startAliveTimePercents[index];
                float end = endAliveTimePercents[index];
                // 根据当前时间计算下一帧
                float aliveTimePercent = realAliveTimePercents[i];//aliveTimePercents[i];
                float speed = data.speeds[i];
                bool restart = data.restarts[i];

                var timeOffset = deltaTime * speed;
                aliveTimePercent += timeOffset;
                /*if (customLifetime != 0)
                {
                    aliveTimePercent = customLifetime;
                }*/
                float frameOffsetTimePercent;
                if (aliveTimePercent < start || restart || aliveTimePercent > (end - 0.5f * timeOffset))
                {
                    aliveTimePercent = start;
                    frameOffsetTimePercent = aliveTimePercent;
                }
                else
                {
                    frameOffsetTimePercent = aliveTimePercent;
                }

                aliveTimePercents[i] = aliveTimePercent;
                realAliveTimePercents[i] = aliveTimePercent;
                
                int frameOffset = 0;
                if (timeOffset > 0)
                {
                    frameOffset = Mathf.FloorToInt(frameOffsetTimePercent / 10000 * allLifeTime / (1/30f)) - Mathf.FloorToInt(start / 10000 * allLifeTime / (1/30f));
                    aliveTimePercents[i] = start + ((1 / 30f) * frameOffset / allLifeTime) * 10000;
                    var offsetIndex = index * 100 + frameOffset;

                    float offsetX = 0;
                    float offsetY = 0;

                    var team = data.team[i];
                    if (team == 0 || team == 1)
                    {
                        offsetX = changeColorOffsetX[offsetIndex];
                        offsetY = changeColorOffsetY[offsetIndex];
                    }
                    else if (team == 3)
                    {
                        offsetX = changeColorOffsetX2[offsetIndex];
                        offsetY = changeColorOffsetY2[offsetIndex];
                    }
                   
                    var startX = startOffsetX[offsetIndex];
                    var startY = startOffsetY[offsetIndex];

                    var rectWidth = this.rectWidth[offsetIndex];
                    var rectHeight = this.rectHeight[offsetIndex];
                    customData[i] = new Vector4(offsetX,offsetY,0,0);
                    customData2[i] = new Vector4(startX,startY,rectWidth,rectHeight);
                }

                if (restart)
                    data.restarts[i] = false;
            }
        }
    }
}
